#!/usr/bin/env python
# -*- coding: utf-8 -*- 
############################################################################
#    Copyright (C) 2007-2008
#                  Ferraro Luciano (aka lux) <luciano.ferraro@gmail.com>
#                  Matto Scacco (aka checkm, scaccom) <matto.scacco@gmail.com>
#
#
#    This program is free software; you can redistribute it and/or modify 
#    it under the terms of the GNU General Public License as published by 
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the
#    Free Software Foundation, Inc.,
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
############################################################################

import gtk
import pango
import time
import menubar
import channels
import messages
import users

class Window (gtk.Window):
    def __init__ (self):
        gtk.Window.__init__(self)
        
        self.hpaned = {}
        self.current_tree = ""
        self.users_lists = {}
        self.messages_lists = {}
                        
        self.connect("destroy", self.quit)
        self.set_title("Merdim")
        self.maximize()
        
        ui = menubar.MenuBar()
        channels_list = self.build_channels_list_frame()
        
        self.main_vbox = gtk.VBox()
        self.hbox = gtk.HBox()
        self.channels_list_vbox = gtk.VBox()
        
        self.channels_list_vbox.pack_start (channels_list[0], True, True, 5)
        self.hbox.pack_start (self.channels_list_vbox, False, True, 5)
        self.main_vbox.pack_start (ui.get_widget("/MenuBar"), False, False)
        self.main_vbox.pack_start (self.hbox, True, True)
        
        self.add(self.main_vbox)
        self.channels_list = channels_list[1]
        self.channels_list.selection.connect('changed', self.changed_tree)

    def build_channels_list_frame (self):     
        channels_list = channels.ChannelsList()
        
        channels_list_frame = gtk.Frame()
        channels_list_frame.add(channels_list)
        
        return (channels_list_frame, channels_list)
    
    def build_messages_frame (self):
        messages_vbox = gtk.VBox()
        messages_hpaned = gtk.HPaned()
        
        #messages_show = messages.MessagesShow()
        
        messages_show = messages.MessagesShow()
        messages_show_frame = gtk.Frame()
        messages_show_frame.add(messages_show)
        
        messages_entry = messages.MessagesEntry()
        messages_entry.connect("activate", self.send)
        
        #messages_hpaned.pack1(messages_show, True, True)
        messages_hpaned.pack2(messages_show_frame, True, True)
        messages_vbox.pack_start(messages_hpaned, True, True, 5)
        messages_vbox.pack_end(messages_entry, False, False, 5)
        
        #messages_frame = gtk.Frame()
        #messages_frame.add(messages_vbox)
        
        return (messages_vbox, messages_show)
    
    def build_users_list_frame (self):
        users_list = users.UsersList()
        
        users_list_frame = gtk.Frame()
        users_list_frame.add(users_list)
        
        return (users_list_frame, users_list)
    
    def build_frame (self, name):
        self.hpaned[name] = gtk.HPaned()
        hpaned = gtk.HPaned()
        
        users_list = self.build_users_list_frame()
        messages = self.build_messages_frame()
        
        hpaned.pack1(messages[0], True, True)
        hpaned.pack2(users_list[0], True, True)
        self.hpaned[name].pack1(hpaned, True, True)
        
        self.users_lists[name] = users_list[1]
        self.messages_lists[name] = [messages[1], 0]
        
        #self.change_frame(name)

    def change_frame (self, name):
        if self.hpaned.has_key(self.current_tree):
            self.hbox.remove(self.hpaned[self.current_tree])
        self.current_tree = name
        self.hbox.pack_start(self.hpaned[name])
        
        self.show_all()

    def changed_tree (self, selection):
        model, paths = selection.get_selected_rows()
        if not paths: return
        paths = paths[0]
        server_name = model.get_value(model.get_iter(paths[0]), 0)
        if len(paths) == 1:
            self.change_frame(server_name)
            self.set_title("Merdim: %s @ %s" % (
            self.conf.nickname[server_name], server_name
            ))
        elif len(paths) == 2:
            channel = self.channels_list.model_map[server_name][1].keys()[paths[1]]
            self.change_frame(server_name+":"+channel)
            self.set_title("Merdim: %s @ %s / %s" % (
            self.conf.nickname[server_name], server_name, channel
            ))

    def styler(self, style):
        styles = {
        "motd":("#990099", "#9966CC"), "chanmsg":("#3F4C6B", "#333333"), 
        "privmsg":("#3F4C6B", "#666666"), "command":("#D01F3C", "#D01F3C"), 
        "irc":("#003300", "#006633"), "self":("#666666", "#333333"), 
        "core":("#990099", "#990099"), "notice":("#9966CC", "black")
        }
        if styles.has_key(style):
            return styles[style]
        else:
            return "black", "black"

    def send(self, text):
        data = text.get_text().encode("utf-8")
        text.set_text("")
        sdata = data.split() #splitted
        #pdata = sdata[0].split("/", 1)
        pdata = " ".join(sdata[1:])
        server = self.current_tree.split(":")[0]
        
        if data in ("\n", "\r", ""): return
        #Cose possibili anche in una tree Server
        elif sdata[0] in ("/quit", "/disconnect", "/q"):
            self.clients[server].quit(pdata)
        elif sdata[0] in ("/ping", "/pong"):
            self.clients[server].irc.ping(sdata[1])
        elif sdata[0] in ("/away", "/afk"):
            self.clients[server].irc.away(pdata)
        elif sdata[0] in ("/notice", "/nctcp"):
            self.clients[server].irc.notice(sdata[1], " ".join(sdata[2:]))
        elif sdata[0] in ("/chanserv", "/cs"):
            self.clients[server].privmsg("ChanServ", pdata)
        elif sdata[0] in ("/nickserv", "/ns"):
            self.clients[server].privmsg("NickServ", pdata)
        elif sdata[0] in ("/nick", "/name", "/nickname"):
            self.clients[server].irc.setNick(sdata[1])
        elif sdata[0] in ("/message", "/msg", "/wisper", "/w"):
            self.clients[server].privmsg(sdata[1], " ".join(sdata[2:]))
        elif sdata[0] in ("/join", "/j"):
            self.clients[server].irc.join(pdata)
        elif sdata[0] in ("/part", "/p", "/leave"):
            self.clients[server].irc.leave(pdata)
        
        elif ":" not in self.current_tree: return
        #Cose possibili solo in un channel (come /kick ecc.)
        elif sdata[0] in ("/me", "/act"):
            self.clients[server].irc.me(self.current_tree.split(":")[1], pdata)
        else:
            self.clients[server].privmsg(self.current_tree.split(":")[1], data)

    def remove_tree(self, server_name):
        self.channels_list.remove_tree(server_name)
        return True #in caso sia andato tutto a buon fine
        #return (False, server_name+":doesnt' exist")
            #in caso server_name non esista nella treeview
    
    def add_tree(self, server_name):
        self.build_frame(server_name)
        self.channels_list.add_tree(server_name)
        self.change_frame(server_name)
        return True #in caso sia andato tutto a buon fine
        #return (False, server_name+":has already been added")
            #in caso server_name gia' esiste nella treeview
    
    def add_subtree(self, server_name, channel_name):
        """ varra' lo stesso per query da altri utenti """
        self.build_frame(server_name+":"+channel_name)
        self.channels_list.add_subtree(server_name, channel_name)
        return True #in caso sia andato tutto a buon fine
        #return (False, server_name+":has already been added")
            #in caso server_name non esiste nella treeview
        #return (False, channel_namee+":has already been added")
            #in caso channel_name gia' esiste nella tree
    
    def remove_subtree(self, server_name, channel_name):
        """ varra' lo stesso per query da altri utenti """
        self.channels_list.remove_subtree(server_name, channel_name)
        name = server_name+":"+channel_name
        self.change_frame(server_name)
        del self.hpaned[name]
        del self.users_lists[name]
        del self.messages_lists[name]
        return True #in caso sia andato tutto a buon fine
        #return (False, server_name+":doesn't exist")
            #in caso server_name non esiste nella treeview
        #return (False, channel_name+":doesn't exist")
            #in caso channel_name non esiste nella tree
    
    def insert_text(self, text, server_name=None, channel_name=None, usertext="*", style=None):
        messages_list = self.messages_lists[self.name_maker(server_name, channel_name)]
        text = text.encode('utf8').rstrip()
        if usertext == "irc": usertext = "*"
        
        style, style2 = self.styler(style)
        
        buffer = messages_list[0].view.buffer
        #if usertext in ("*", "--"):
        #    buffer.insert_text(None, "\n "+spacer+"("+usertext+") ", style)
        #else:
        
        if messages_list[1] < len(usertext): messages_list[1] = len(usertext)
        space = messages_list[1]-len(usertext)+2
        if usertext not in ("*", "--"): usertext = "<"+usertext+">";space-=2
        ptime = time.strftime("[%H:%M] " + " " * space)
        
        buffer.insert_text(None, ptime)
        #userbuffer = messages_list[0].view.buffer
        buffer.insert_text(None, usertext+" ", style, pango.WEIGHT_BOLD)
        buffer.insert_text(None, text + "\n", style2)
        
        #line_count = buffer.get_line_count()-userbuffer.get_line_count()
        #if line_count > 0:
        #    userbuffer.insert_text(None, "\n"*(line_count-1))
        return True #in caso sia andato tutto a buon fine
        #return (False, server_name+":doesn't exist")
            #in caso server_name non esiste nella treeview
        #return (False, channel_name+":doesn't exist in:"+server_name)
            #in caso channel_name non si trovi nel tree server_name
        #return (False, str(text)+":isn't a valid str")
            #in caso text non sia una str o sia un tipo 'indecifrabile' di str
            # succede spesso con testi molto grandi, tipo inviati dal server, roba strana
    
    def add_user(self, user, server_name, channel_name):
        self.users_lists[server_name+":"+channel_name].add_user(user)
        return True #in caso sia andato tutto a buon fine
        #return (False, server_name+":doesn't exist")
            #in caso server_name non esiste
        #return (False, channel_name+":doesn't exist in:"+server_name)
            #in caso channel_name non si trovi in server_name
        #return (False, user+":has already been added")
            #in caso user esitesse gia' nella userlist

    def remove_user(self, user, server_name, channel_name):
        self.users_lists[server_name+":"+channel_name].remove_user(user)
        return True #in caso sia andato tutto a buon fine
        #return (False, server_name+":doesn't exist")
            #in caso server_name non esiste
        #return (False, channel_name+":doesn't exist in:"+server_name)
            #in caso channel_name non si trovi in server_name
        #return (False, user+":doesn't exist")
            #in caso user non esistesse gia' nell userlist

    def name_maker(self, server_name=None, channel_name=None):
        if server_name == None: return self.current_tree
        elif channel_name == None: return server_name
        else: return server_name+":"+channel_name

    def start(self):
        self.show_all()

    def quit(self, action):
        gtk.main_quit()
        for server in self.clients:
            try: self.clients[server].quit()
            except: print "Error: Couldn't quit from "+server
        time.sleep(1)
        raise SystemExit

def test ():
    init = Window()
    init.start()
    try:
        gtk.main()
    except KeyboardInterrupt:
        raise SystemExit
    
if __name__ == "__main__":
    test()
